/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Canadian Weather.
 *
 * The Initial Developer of the Original Code is
 *   George Bradt.
 *
 * Portions created by the Initial Developer are Copyright (C) 2011
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   George Bradt.
 *
 * Credits:
 *   Sun icons from Icons-Land at http://www.icons-land.com/vista-weather-icons.php
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// Hack required because there is no way to replicate dynamic widget content to new windows (SDK 1.0b5).
self.port.emit('newWindow');

// Remove the text.
self.port.on('removeText', function() {
    var displayString = document.getElementById('canw-widgetText');

    // Clear existing text node.
    while ( displayString.firstChild ) {
        displayString.removeChild(displayString.firstChild);
    }
    
    self.port.emit('textWidth', 0);
});

// Insert the text to be displayed, then determine and emit it's length in pixels.
self.port.on('insertTextAndMeasure', function(aText) {
    var displayString = document.getElementById('canw-widgetText');
    displayString.appendChild(document.createTextNode(aText));
    self.port.emit('textWidth', displayString.offsetWidth);
});

// Style the displayed text.
self.port.on('styleText', function(aOptions, aWarnings) {
    var displayString = document.getElementById('canw-widgetText');
    
    if ( displayString.offsetWidth < 1 ) {
        return;
    }

    // Font properties.
    if ( aOptions.toolbarStyle.bold ) {
        displayString.style.setProperty('font-weight', 'bold', '');
    }
    else {
        displayString.style.removeProperty('font-weight');
    }

    if ( aOptions.toolbarStyle.italic ) {
        displayString.style.setProperty('font-style', 'italic', '');
    }
    else {
        displayString.style.removeProperty('font-style');
    }

    // Color properties.
    var activeEventIndex = 0;

    if ( aOptions.toolbarColorEnabled && aWarnings.length > 0 ) {
        // Set colors based on most recent, and active, event. There may not be an active event.
        if ( aWarnings[1].type == 'Ended' ) {
            // Perhaps another event that hasn't ended yet.
            for ( let i = 2; i < aWarnings.length; i++ ) {
                if ( aWarnings[1].description != aWarnings[i].description &&
                     aWarnings[i].type != 'Ended' ) {
                    activeEventIndex = i;
                }
            }
        }
        else {
            activeEventIndex = 1;
        }
    }

    displayString.style.removeProperty('color');
    displayString.style.removeProperty('background-color');

    if ( activeEventIndex ) {
        switch ( aWarnings[activeEventIndex].priority ) {
            case 'Low':
                if ( aOptions.toolbarStyle.color.priorityLow[0] ) {
                    displayString.style.setProperty('color', aOptions.toolbarStyle.color.priorityLow[0], '');
                }

                if ( aOptions.toolbarStyle.color.priorityLow[1] ) {
                    displayString.style.setProperty('background-color', aOptions.toolbarStyle.color.priorityLow[1], '');
                }

                break;

            case 'Medium':
                if ( aOptions.toolbarStyle.color.priorityMedium[0] ) {
                    displayString.style.setProperty('color', aOptions.toolbarStyle.color.priorityMedium[0], '');
                }

                if ( aOptions.toolbarStyle.color.priorityMedium[1] ) {
                    displayString.style.setProperty('background-color',aOptions.toolbarStyle.color.priorityMedium[1], '');
                }

                break;

            case 'High':
                if ( aOptions.toolbarStyle.color.priorityHigh[0] ) {
                    displayString.style.setProperty('color', aOptions.toolbarStyle.color.priorityHigh[0], '');
                }

                if ( aOptions.toolbarStyle.color.priorityHigh[1] ) {
                    displayString.style.setProperty('background-color', aOptions.toolbarStyle.color.priorityHigh[1], '');
                }

                break;

            case 'Urgent':
                if ( aOptions.toolbarStyle.color.priorityUrgent[0] ) {
                    displayString.style.setProperty('color', aOptions.toolbarStyle.color.priorityUrgent[0], '');
                }

                if ( aOptions.toolbarStyle.color.priorityUrgent[1] ) {
                    displayString.style.setProperty('background-color', aOptions.toolbarStyle.color.priorityUrgent[1], '');
                }

                break;

            default:
                self.port.emit('unexpectedPriorityError', aWarnings[activeEventIndex].priority);
                break;
        }
    }
    else {
        if ( aOptions.toolbarStyle.color.normal[0] ) {
            displayString.style.setProperty('color', aOptions.toolbarStyle.color.normal[0], '');
        }

        if ( aOptions.toolbarStyle.color.normal[1] ) {
            displayString.style.setProperty('background-color', aOptions.toolbarStyle.color.normal[1], '');
        }
    }
    
    // Font changes may alter width.
    self.port.emit('textWidth', displayString.offsetWidth);
});

// Select and display the widget image.
// The Environment Canada icon code can cover different conditions, so those codes can be
// mapped to multiple Canadian Weather icon codes. Thus our icons are a more fine-grained
// representation of the current weather condition.
//
// parameter aConditionIconCode: the Environment Canada icon code.
// parameter aConditionText: the Environment Canada condition, which is searched for keywords.
// parameter aUrl: URL of image file, which gets updated with appropriate icon code.
self.port.on('showImage', function(aConditionIconCode, aConditionText, aUrl) {
    var myIconCode;
    var conditionText = aConditionText.toLowerCase();
    
    switch ( aConditionIconCode ) {
        case '00':
            // Sunny.
            // Fall through.
        
        case '01':
            // Mainly Sunny.
            myIconCode = '00';
            break;

        case '02':
            // Partly Cloudy.
            myIconCode = '02';
            break;

        case '03':
            // Mostly Cloudy.
            myIconCode = '03';
            break;

        case '34':
            // Night.
            // Fall through.
        
        case '04':
            // Increasing Cloud.
            myIconCode = '04';
            break;

        case '35':
            // Night.
            // Fall through.
        
        case '05':
            // Decreasing Cloud.
            myIconCode = '05';
            break;

        case '06':
            // Light Rainshower.
            myIconCode = '06';
            break;

        case '07':
            // Mixed Rain and Snow Shower.
            myIconCode = '07';
            break;

        case '08':
            // Light Snowshower.
            myIconCode = '08';
            break;

        case '39':
            // Night.
            // Fall through.
        
        case '09':
            if ( conditionText.indexOf('recent') != -1 ) {
                if ( conditionText.indexOf('rain') != -1 ) {
                    // Recent Thunderstorm with Rain.
                    myIconCode = '11';
                }
                else {
                    // Recent Thunderstorm.
                    myIconCode = '10';
                }
            }
            else {
                // Lightning Visible; Thunderstorm without Precipitation.
                myIconCode = '09';
            }
            
            break;

        case '10':
            // Cloudy.
            myIconCode = '12';
            break;

        case '11':
            if ( conditionText.indexOf('recent') != -1 ) {
                // Recent Rainshower.
                myIconCode = '14';
            }
            else if ( conditionText.indexOf('distant') != -1 ) {
                // Distant Precipitation.
                myIconCode = '57';
            }
            else {
                // Squalls.
                myIconCode = '13';
            }
            
            break;

        case '12':
            if ( conditionText.indexOf('recent') != -1 ) {
                // Recent Rain.
                myIconCode = '14';
            }
            else if ( conditionText.indexOf('drizzle') != -1 ) {
                // Mixed Rain and Drizzle.
                myIconCode = '16';
            }
            else {
                // Light Rain.
                myIconCode = '15';
            }
            
            break;

        case '13':
            if ( conditionText.indexOf('heavy') != -1 ) {
                if ( conditionText.indexOf('drizzle') != -1 ) {
                    // Heavy Mixed Rain and Drizzle.
                    myIconCode = '17';
                }
                else {
                    // Heavy Rain; Heavy Rainshower.
                    myIconCode = '18';
                }
            }
            else {
                // Rain; Rainshower.
                myIconCode = '19';
            }
            
            break;

        case '14':
            if ( conditionText.indexOf('recent') != -1 ) {
                // Recent Freezing Precipitation.
                myIconCode = '22';
            }
            else if ( conditionText.indexOf('drizzle') != -1 ) {
                // Freezing drizzle; Light Freezing Drizzle.
                myIconCode = '20';
            }
            else {
                // Freezing rain; Light Freezing Rain; Ice Pellets.
                myIconCode = '21';
            }
            
            break;

        case '15':
            if ( conditionText.indexOf('recent') != -1 ) {
                // Recent Rain and Snow.
                myIconCode = '25';
            }
            else if ( conditionText.indexOf('heavy') != -1 ) {
                // Heavy Mixed Rain and Snow Shower; Heavy Rain and Snow.
                myIconCode = '23';
            }
            else {
                // Rain and Snow.
                myIconCode = '24';
            }
            
            break;

        case '16':
            if ( conditionText.indexOf('recent') != -1 ) {
                if ( conditionText.indexOf('hail') != -1 ) {
                    // Recent Hail.
                    myIconCode = '27';
                }
                else {
                    // Recent Snow; Recent Snowshower.
                    myIconCode = '28';
                }
            }
            else {
                // Light Snow.
                myIconCode = '26';
            }
            
            break;

        case '17':
            // Snow; Heavy Snowshower.
            myIconCode = '29';
            break;

        case '18':
            // Heavy Snow.
            myIconCode = '30';
            break;

        case '19':
            if ( conditionText.indexOf('recent') != -1 ) {
                if ( conditionText.indexOf('hail') != -1 ) {
                    // Recent Thunderstorm with Hail; Recent Thunderstorm with Heavy Hail.
                    myIconCode = '33';
                }
                else {
                    // Recent Thunderstorm with Heavy Rain.
                    myIconCode = '34';
                }
            }
            else if ( conditionText.indexOf('heavy') != -1 ) {
                if ( conditionText.indexOf('hail') != -1 ) {
                    // Heavy Thunderstorm with Hail.
                    myIconCode = '31';
                }
                else {
                    // Heavy Thunderstorm with Rain.
                    myIconCode = '32';
                }
            }
            else {
                if ( conditionText.indexOf('hail') != -1 ) {
                    // Thunderstorm with Hail.
                    myIconCode = '36';
                }
                else {
                    // Thunderstorm with Rain.
                    myIconCode = '35';
                }
            }
            
            break;

        case '23':
            // Haze.
            myIconCode = '37';
            break;

        case '24':
            if ( conditionText.indexOf('recent') != -1 ) {
                // Recent Fog.
                myIconCode = '58';
            }
            else {
                // Various Fog/Mist.
                myIconCode = '38';
            }
            
            break;

        case '40':
            // Heavy Blowing Snow; Blowing Snow.
            // Fall through.
        
        case '25':
            if ( conditionText.indexOf('heavy') != -1 ) {
                // Heavy Drifting Snow.
                myIconCode = '40';
            }
            else {
                // Drifting Snow.
                myIconCode = '39';
            }
            
            break;

        case '26':
            // Ice Crystals; Snow Crystals.
            myIconCode = '59';
            break;

        case '27':
            if ( conditionText.indexOf('heavy') != -1 ) {
                // Heavy Hail; Heavy Snow Pellets.
                myIconCode = '42';
            }
            else {
                // Hail; Light Snow Pellets.
                myIconCode = '41';
            }
            
            break;

        case '28':
            if ( conditionText.indexOf('recent') != -1 ) {
                // Recent Drizzle.
                myIconCode = '60';
            }
            else if ( conditionText.indexOf('heavy') != -1 ) {
                // Heavy Drizzle.
                myIconCode = '44';
            }
            else {
                // Light Drizzle; Drizzle; Snow Grains.
                myIconCode = '43';
            }
            
            break;

        case '99':
            // Default.
            // Fall through.

        case '29':
            // Not Reported.
            myIconCode = '99';
            break;

        case '30':
            // Clear (night).
            // Fall through.

        case '31':
            // Mainly Clear (night).
            myIconCode = '45';
            break;

        case '32':
            // Partly Cloudy (night).
            myIconCode = '46';
            break;

        case '33':
            // Mostly Cloudy (night).
            myIconCode = '47';
            break;

        case '36':
            // Light Rainshower.
            myIconCode = '48';
            break;

        case '37':
            // Mixed Rain and Snow Shower.
            myIconCode = '49';
            break;

        case '38':
            // Light Snowshower.
            myIconCode = '50';
            break;

        case '41':
            // Funnel Cloud.
            myIconCode = '51';
            break;

        case '42':
            // Tornado.
            myIconCode = '52';
            break;

        case '44':
            // Smoke.
            myIconCode = '53';
            break;

        case '45':
            if ( conditionText.indexOf('recent') != -1 ) {
                // Recent Dust or Sand Storm.
                myIconCode = '55';
            }
            else if ( conditionText.indexOf('thunderstorm') != -1 ) {
                // Thunderstorm with Sand or Dust Storm.
                myIconCode = '56';
            }
            else {
                // Dust; Dust Devils; Sand or Dust Storm; Severe Sand or Dust Storm.
                myIconCode = '54';
            }
            
            break;

        default:
            // The flag icon.
            myIconCode = '99';
            break;
    }
    
    var image = document.getElementById('canw-widgetImage');
    image.setAttribute('src', aUrl.slice(0, -6) + myIconCode + '.png');
    image.hidden = false;
});

// Hide the image.
self.port.on('hideImage', function() {
    var image = document.getElementById('canw-widgetImage');
    image.hidden = true;
});

// Listen for click events and emit the user-defined event.
// to the add-on code.
this.addEventListener('click', function(aEvent) {
    if( aEvent.button == 0 && aEvent.shiftKey == false ) {
        self.port.emit('left-click');
    }
    else if( aEvent.button == 2 || ( aEvent.button == 0 && aEvent.shiftKey == true ) ) {
        self.port.emit('right-click');
    }

    aEvent.preventDefault();
}, true);

// Listen for mouseover events and emit target nodeName to the add-on code.
this.addEventListener('mouseover', function(aEvent) {
    self.port.emit('setTooltip', aEvent.target.nodeName);
}, true);